#include <iostream>
#include <gtest/gtest.h>
#include <vector>
#include "../mqserver/mq_virtualhost.hpp"
mq_zxws::VirtualHost::ptr vhp;
using empty_map = std::unordered_map<std::string, std::string>;
class Hosttest: public testing::Test{
public:
    static void SetUpTestCase(){
        vhp = std::make_shared<mq_zxws::VirtualHost>("host1","./host1/message","./host1/host1.db");
        vhp->declareExchange("exchange1", mq_zxws::ExchangeType::DIRECT, true, false, empty_map());
        vhp->declareExchange("exchange2", mq_zxws::ExchangeType::DIRECT, true, false, empty_map());
        vhp->declareExchange("exchange3", mq_zxws::ExchangeType::DIRECT, true, false, empty_map());

        vhp->declareQueue("queue1", true, false, false, empty_map());
        vhp->declareQueue("queue2", true, false, false, empty_map());
        vhp->declareQueue("queue3", true, false, false, empty_map());

        vhp->bind("exchange1", "queue1", "news.music.pop", true);
        vhp->bind("exchange1", "queue2", "news.music.pop", true);
        vhp->bind("exchange1", "queue3", "news.music.pop", true);

        vhp->bind("exchange2", "queue1", "news.music.pop", true);
        vhp->bind("exchange2", "queue2", "news.music.pop", true);
        vhp->bind("exchange2", "queue3", "news.music.pop", true);

        vhp->bind("exchange3", "queue1", "news.music.pop", true);
        vhp->bind("exchange3", "queue2", "news.music.pop", true);
        vhp->bind("exchange3", "queue3", "news.music.pop", true);

        vhp->basicPublish("queue1", nullptr, "hello world-1");
        vhp->basicPublish("queue1", nullptr, "hello world-2");
        vhp->basicPublish("queue1", nullptr, "hello world-3");
    }
    static void TearDownTestCase(){
         vhp->clear();
    }
public:
};

TEST_F(Hosttest, init_test){
    ASSERT_EQ(vhp->existsExchange("exchange1"), true);
    ASSERT_EQ(vhp->existsExchange("exchange2"), true);
    ASSERT_EQ(vhp->existsExchange("exchange3"), true);

    ASSERT_EQ(vhp->existsQueue("queue1"), true);
    ASSERT_EQ(vhp->existsQueue("queue2"), true);
    ASSERT_EQ(vhp->existsQueue("queue3"), true);

    ASSERT_EQ(vhp->existsBinding("exchange1", "queue1"), true);
    ASSERT_EQ(vhp->existsBinding("exchange1", "queue2"), true);
    ASSERT_EQ(vhp->existsBinding("exchange1", "queue3"), true);

    ASSERT_EQ(vhp->existsBinding("exchange2", "queue1"), true);
    ASSERT_EQ(vhp->existsBinding("exchange2", "queue2"), true);
    ASSERT_EQ(vhp->existsBinding("exchange2", "queue3"), true);

    ASSERT_EQ(vhp->existsBinding("exchange3", "queue1"), true);
    ASSERT_EQ(vhp->existsBinding("exchange3", "queue2"), true);
    ASSERT_EQ(vhp->existsBinding("exchange3", "queue3"), true);

    mq_zxws::MessagePtr msg1 = vhp->basicConsume("queue1");
    ASSERT_EQ(msg1->payload().body(), std::string("hello world-1"));
}
TEST_F(Hosttest, remove_exchange){
    vhp->deleteExchange("exchange1");
    ASSERT_EQ(vhp->existsExchange("exchange1"), false);
    
    ASSERT_EQ(vhp->existsBinding("exchange1", "queue1"), false);
    ASSERT_EQ(vhp->existsBinding("exchange1", "queue2"), false);
    ASSERT_EQ(vhp->existsBinding("exchange1", "queue3"), false);
}

TEST_F(Hosttest, remove_queue){
    vhp->deleteQueue("queue1");
    ASSERT_EQ(vhp->existsQueue("queue1"), false);
    
    ASSERT_EQ(vhp->existsBinding("exchange1", "queue1"), false);
    ASSERT_EQ(vhp->existsBinding("exchange2", "queue1"), false);
    ASSERT_EQ(vhp->existsBinding("exchange3", "queue1"), false);

    mq_zxws::MessagePtr msg1 = vhp->basicConsume("queue1");
    ASSERT_EQ(msg1.get(), nullptr);
    
}

int main(int argc, char* argv[])
{
    testing::InitGoogleTest(&argc, argv);
    int ret = RUN_ALL_TESTS();
    return 0;
}